<template>
    <component :is="defaults[0]" />
    <button @click="sub">-</button>
    <span :style="attrs.style">{{num}}</span>
    <button @click="add">+</button>
    <p>计算属性：{{sum}}</p>
    <button @click="updateUser('数据穿透-子组件')">{{user}}</button>
    <component :is="defaults[1]" />
</template>

<script>
  import {ref,watch,watchEffect,computed,inject} from 'vue'
  export default {
    inheritAttrs:false,
    props:{
      init:{
        type:Number,
        default:3
      }
    },
    emits:['change','fatherChange'],
    // 组合api
    setup(props,context) {
      const {emit,expose,attrs,slots} = context;
      // 在setup中不要使用data,computed,methods
      // let num = ref(2); //用ref包装后，数据是响应式的。在使用num时，利用num.Value取值
      let num = ref(props.init);  //setup中使用props
      //计算属性
      let sum = computed(() => num.value + 100);
      let add = () => {
        num.value++;
        emit('change',num.value); //返回自定义事件
        emit('fatherChange'); //父组件直接读取子组件数据，所以不需要传数据
      };
      let sub = () => {
        num.value--;
        emit('change',num.value); //返回自定义事件
        emit('fatherChange'); //父组件直接读取子组件数据，所以不需要传数据
      }
      // 组合api使用watch
      // watch(num,(v) => {
      //   if(v < 0){
      //     this.num = 0;
      //   }
      // });

      // watchEffect先自动执行一次，监听响应式数据时执行，也可以根据返回值，让监听失效
      const stop = watchEffect(() => {
        // console.log('aaa');
        // console.log(num.value);
        if(num.value < 0){
          num.value = 0;
        }
        emit('change',num.value); //返回自定义事件
        emit('fatherChange'); //父组件直接读取子组件数据，所以不需要传数据
      });
      // stop(); //监听失效

      // 读取插槽里的默认插槽
      const defaults = slots.default();

      // 通过expose暴露给父组件想暴露的参数
      expose({num});

      const user = inject('user',"后盾");
      const updateUser = inject('updateUser');

      return{num,sub,add,attrs,defaults,sum,user,updateUser};  //将变量return出去后才能在外部使用
    },
    // 选项api
    // data() {
    //   return {
    //     num:2
    //   }
    // },
    // watch:{
    //   num(v){
    //     if(v < 0){
    //       this.num = 0;
    //     }
    //   }
    // }
    // methods:{
    //   add() {
    //     this.num++;
    //   }
    // }
  }
</script>

<style lang="scss" scoped>

</style>